import libtcodpy as libtcod

import console
import image
import menu
import splash

class Tile(object):
    def __init__(self, light, dark, passable, transparent, char=None, color=libtcod.white, name=None, speed=0):
        self.light = light
        self.dark = dark
        
        self.passable = passable
        self.transparent = transparent
        
        self.char = char
        self.color = color
        self.name = name

        self.speed = speed

class Light(Tile):
    def __init__(self, color, radius, x=None, y=None, char=libtcod.CHAR_RADIO_SET, 
                 char_color=None, name='light', passable=False):
        if char_color is None:
            char_color = libtcod.white
        super(Light, self).__init__(color, color, passable, True, char, char_color, name)
        self.radius = radius
        self.x = x
        self.y = y

    def __repr__(self):
        if None in (self.x, self.y):
            return "Light(%r, %d)" % (self.color, self.radius)
        else:
            return "Light(%r, %d, %d, %d)" % (self.color, self.radius, self.x, self.y)


class Water(Tile):
    def __init__(self):
        super(Water, self).__init__(libtcod.light_sky, libtcod.light_sky, False, True, 
                                    libtcod.CHAR_BLOCK1, libtcod.sky, name='water')

class ItemSelector(object):
    def __init__(self, items, title=None, header=None, footer=None):
        self.items = items 
        self.title = title
        self.header = header
        self.footer = footer

    def show(self, console):
        items_width, items_height = console.width / 2, min(max(len(self.items), 10), console.height * 2 / 3)
        x, y = (console.width - items_width) / 2, 3

        # Callback for item description
        self.description = None
        def menu_item(item):
            if hasattr(item, 'long_description'):
                description_text = "%s" % desc_cap(item.long_description)
                description_width = console.width * 2 / 3
                description_height = 2 + console.height_left_rect(0, 0, description_width - 2,
                                                              console.height, description_text)
                if self.description:
                    if (self.description.text == description_text):
                        return
                    self.description.remove()  # Remove last description window
                self.description = splash.Splash(description_text, description_width, description_height, border=True,
                                                 title=item.name, wrap=True, key_hit=False, background_alpha=0.8)
                desc_x, desc_y = (console.width - description_width) / 2, y + items_height + 2
                self.description.render(console, x=desc_x, y=desc_y)
            elif self.description:
                self.description.remove()
                self.description = None

        # Show menu
        selector = menu.Menu(items_width, items_height+2, self.title, self.items, header=self.header,
                        footer=self.footer, callback=menu_item)
        item = selector.show(console, x, y, background_alpha=0.8)
        if self.description:
            self.description.remove()

        return item

class ResultScreen(object):
    "It's way early.  This is a poor man's subclass."
    def __init__(self, root, title, text):
        self.root = root
        self.text = text + '  Press any key.'
        self.title = title

        self.width = self.root.width / 2
        self.height = 2 + self.root.height_center_rect(0, 0, self.width - 2, self.root.height, text)
        self.x, self.y = (self.root.width - self.width) / 2, (self.root.height - self.height) / 2
        self.result = splash.Splash(text, width=self.width, height=self.height, border=True, title=title, center=True,
                                    key_hit=True, wrap=True, background_alpha=0.75)

    def render(self, key=None):
        self.result.render(self.root, key, self.x, self.y)

    @property
    def done(self):
        return self.result.done


def desc_cap(description):
    if not description:
        return ""
    first = description[0].upper()
    return ''.join([first, description[1:]])


def find_tile(map, name):
    for y, row in enumerate(map):
        for x, tile in enumerate(row):
            if map[y][x].name == name:
                return (x, y)

def get_noise(width, height, color, zoom, method=libtcod.noise_simplex):
    z = float(zoom)
    r = color.r / 255.0
    g = color.g / 255.0
    b = color.b / 255.0

    noise = libtcod.noise_new(2)

    img = image.Image(width=width, height=height)
    for y in xrange(height):
        for x in xrange(width):
            f = [z * x / width, z * y / height]
            val = method(noise, f)
            #val = libtcod.noise_simplex(noise, f)
            #val = libtcod.noise_wavelet(noise, f)
            c = (val + 1.0) / 2.0 * 255.0
            col = libtcod.Color(int(c * r), int(c * g), int(c * b)) * color
            img.put_pixel(x, y, col)
    return img

def read_noise(file, width, height, color, zoom, write=False, method=libtcod.noise_simplex):
    try:
        img = image.Image()
        img.load(file)
        size = img.size
    except:
        print "Building background.  This may take a moment."
        img = get_noise(width, height, color, zoom, method)
        if write: img.save(file)
    else:
        if size != (width, height):
            img = get_noise(width, height, color, zoom, method)
            if write: img.save(file)

    return img

def get_name(root):
    valid = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_' ,.!<>/?{}[]\\|=+@#$%^&*`~"

    width, height = 38, 8
    bak = console.Console(root.width, root.height)
    con = console.Console(width, height)
    root.blit(0, 0, root.width, root.height, bak, 0, 0)

    name = ''
    done = False
    while not done:
        con.foreground = libtcod.white
        con.frame(0, 0, width, height, True, libtcod.BKGND_SET)
        con.print_center(width / 2, 2, libtcod.BKGND_NONE, "Dude, What's Yer Name?")
        con.print_left(3, 5, libtcod.BKGND_NONE, '@ <- [%s]' % (' ' * 25))
        con.putchar(9 + len(name), 5, libtcod.CHAR_BLOCK1, libtcod.BKGND_NONE)
        con.foreground = libtcod.red
        con.print_left(9, 5, libtcod.BKGND_NONE, name)

        bak.blit(0, 0, bak.width, bak.height, root, 0, 0)
        con.blit(0, 0, width, height, root, (bak.width - width) / 2, bak.height - height - 2)
        root.flush()

        key = root.wait_for_keypress(True)
        if key.vk == libtcod.KEY_BACKSPACE:
            name = name[:-1]
        elif key.vk in (libtcod.KEY_KPENTER, libtcod.KEY_ENTER):
            if not name.strip():
                name = 'El Duderino'
            done = True
        
        char = chr(key.c)
        if char in valid:
            name = ('%s%s' % (name, char))[:24]

    return name




        












